
from django.db import transaction
from rest_framework import status
from rest_framework.mixins import ListModelMixin
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.viewsets import GenericViewSet

from py_web.common.auth.MyAuth import MyAuth
from py_web.security.SecuritySerialization import MenuSerializer
from py_web.security.models import Menu, RoleMenu
from py_web.user.Filter import MenuFilter
from py_web.user.views.views import roleMenuTreeselect, saveOrUpdateMenu

# 获取菜单树接口
class TreeselectMenu(MyAuth, APIView):

    def get(self, request):
        trees = roleMenuTreeselect()
        return Response(trees)


# 查询所有菜单父子列表
class MenuParentChildList(MyAuth, ListModelMixin, GenericViewSet):
    queryset = Menu.objects.all().order_by('orderNum')
    # 拦截器
    filterset_class = MenuFilter

    serializer_class = MenuSerializer

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())

        serializer = self.get_serializer(queryset, many=True)

        menus = serializer.data
        # 树化
        all: dict = {}
        trees = []

        # 第一层
        for m in menus:
            if m['parentId'] == 0:
                # 保证有children这么个字段
                m['children'] = []
                trees.append(m)
            all[m['menuId']] = m

        # 第二层
        for m in menus:
            try:
                # 如果查不到会报错
                parent = all[m['parentId']]
            except:
                continue
            try:
                parent['children']
            except:
                parent['children'] = []
            m['children'] = []
            # 组装树信息
            parent['children'].append(m)

        # 第三层
        threeMenus = []
        for m in menus:
            if m['menuType'] is 'F':
                threeMenus.append(m)

        for tree in trees:
            for menu in tree['children']:
                menu['children'] = []

        for tree in trees:
            for twomenu in tree['children']:
                for threeMenu in threeMenus:
                    if threeMenu['parentId'] is twomenu['menuId']:
                        twomenu['children'].append(threeMenu)

        return Response(trees, status=status.HTTP_200_OK)


# 获取菜单目录类型
class GetMenuToML(MyAuth, APIView):
    def get(self, request: Request, *args, **kwargs) -> Response:
        menu = Menu.objects.filter(menuType='M')
        serializer = MenuSerializer(instance=menu, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)


# 新增菜单
class SaveMenu(MyAuth, APIView):
    @transaction.atomic
    def post(self, request: Request, *args, **kwargs) -> Response:
        saveOrUpdateMenu(request, "S")

        return Response(status=status.HTTP_200_OK)


# 删除菜单
class DeleteMenu(MyAuth, APIView):
    @transaction.atomic
    def delete(self, request: Request, *args, **kwargs) -> Response:
        # 有子菜单的不能删，有绑定关系的删除绑定关系
        menuId = request.query_params['menuId']
        menu = Menu.objects.filter(parentId=menuId)

        if len(menu) > 0:
            return Response("请先删除子菜单", status=status.HTTP_400_BAD_REQUEST)

        roleMenu = RoleMenu.objects.filter(menuId=menuId)
        if roleMenu:
            roleMenu.delete()

        Menu.objects.get(menuId=menuId).delete()
        return Response(status=status.HTTP_200_OK)

# 修改
class UpdateMenu(MyAuth, APIView):
    @transaction.atomic
    def put(self, request: Request, *args, **kwargs) -> Response:
        saveOrUpdateMenu(request, "U")
        return Response(status=status.HTTP_200_OK)